﻿using AutoTask.Collect.Model;
using AutoTask.Model;
using RpcClient;
using RpcClient.Collect;
using RpcHelper;
using RpcHelper.Error;
using RpcModel;

namespace AutoTask.Service.Helper
{
    internal class TaskItemHelper
    {
        public static TaskExecLog[] ExecTask(AutoTaskItem item, int regionId)
        {
            List<TaskExecLog> logs = new List<TaskExecLog>();
            if (item.SendType == TaskSendType.指令)
            {
                _SendDictate(item, regionId, logs);
            }
            else if (item.SendType == TaskSendType.URI)
            {
                _SendHttp(item, logs);
            }
            else if (item.SendType == TaskSendType.广播)
            {
                _SendBroadcast(item, regionId, logs);
            }
            return logs.ToArray();
        }
        private static void _SendDictate(AutoTaskItem item, int regionId, List<TaskExecLog> logs)
        {
            RpcParamConfig rpcConfig = item.SendParam.RpcConfig;
            RpcSendConfig config = rpcConfig.SendConfig;
            IRemoteConfig send = new IRemoteConfig(config.SysDictate, config.IsReply)
            {
                TimeOut = item.TimeOut,
                IsAllowRetry = item.RetryNum.HasValue,
                RetryNum = item.RetryNum,
                IsSync = !config.LockColumn.IsNull(),
                RpcMerId = rpcConfig.RpcMerId,
                RegionId = regionId,
                SystemType = rpcConfig.SystemType
            };
            send = send.ConvertInto(config);
            TaskExecLog result = new TaskExecLog
            {
                begin = DateTime.Now,
                logRange = item.LogRange
            };
            if (!RemoteCollect.Send(send, rpcConfig.MsgBody, out string error))
            {
                result.end = DateTime.Now;
                result.isFail = true;
                result.errorId = LocalErrorManage.GetErrorId(error);
            }
            else
            {
                result.end = DateTime.Now;
            }
            logs.Add(result);
        }
        private static TaskExecLog _SendHttp(string data, HttpRequestSet config, Uri uri)
        {
            TaskExecLog result = new TaskExecLog
            {
                begin = DateTime.Now
            };
            try
            {
                HttpResponseRes res = HttpHelper.SendRequest(uri, data, config);
                result.end = DateTime.Now;
                result.result = res.Content;
                if (res.StatusCode != System.Net.HttpStatusCode.OK)
                {
                    result.isFail = true;
                    result.errorId = LocalErrorManage.GetErrorId(string.Concat("http.error.", (int)res.StatusCode));
                }
                return result;
            }
            catch (Exception e)
            {
                result.end = DateTime.Now;
                ErrorException error = ErrorException.FormatError(e);
                error.SaveLog("Task");
                result.errorId = LocalErrorManage.GetErrorId(error.ErrorCode);
                return result;
            }
        }
        private static void _SendHttp(AutoTaskItem item, List<TaskExecLog> logs)
        {
            HttpParamConfig param = item.SendParam.HttpConfig;
            HttpRequestSet config = new HttpRequestSet(param.RequestMethod, param.ReqType, param.AnalogType, param.Referer);
            if (item.TimeOut.HasValue)
            {
                config.Timeout = item.TimeOut.Value * 1000;
            }
            TaskExecLog log = _SendHttp(param.PostParam, config, param.Uri);
            log.logRange = item.LogRange;
            logs.Add(log);
            if (log.isFail && item.RetryNum.HasValue)
            {
                for (int i = 0; i < item.RetryNum.Value; i++)
                {
                    log = _SendHttp(param.PostParam, config, param.Uri);
                    logs.Add(log);
                    if (!log.isFail)
                    {
                        break;
                    }
                }
            }

        }
        private static void _SendBroadcast(AutoTaskItem item, int regionId, List<TaskExecLog> logs)
        {
            RpcBroadcastConfig broadcast = item.SendParam.BroadcastConfig;
            RpcParamConfig rpcConfig = item.SendParam.RpcConfig;
            RpcSendConfig config = broadcast.SendConfig;
            IRemoteConfig remote = new IRemoteConfig(config.SysDictate, config.IsReply)
            {
                TimeOut = item.TimeOut,
                IsAllowRetry = item.RetryNum.HasValue,
                RetryNum = item.RetryNum,
                IsSync = !config.LockColumn.IsNull(),
                RpcMerId = rpcConfig.RpcMerId,
                RegionId = regionId,
                SystemType = rpcConfig.SystemType
            };
            IRemoteBroadcast send = new IRemoteBroadcast(config.SysDictate, broadcast.IsOnly, broadcast.TypeVal)
            {
                IsCrossGroup = broadcast.IsCrossGroup,
                RpcMerId = rpcConfig.RpcMerId,
                ServerId = broadcast.ServerId,
                BroadcastType = broadcast.BroadcastType,
                IsExclude = broadcast.IsExclude,
                RegionId = regionId,
                IsOnly = broadcast.IsOnly,
                RemoteConfig = remote
            };
            TaskExecLog result = new TaskExecLog
            {
                begin = DateTime.Now,
                logRange = item.LogRange
            };
            try
            {
                RemoteCollect.BroadcastMsg(send, broadcast.MsgBody);
                result.end = DateTime.Now;
            }
            catch (Exception e)
            {
                result.end = DateTime.Now;
                ErrorException error = ErrorException.FormatError(e);
                error.SaveLog("Task");
                result.errorId = LocalErrorManage.GetErrorId(error.ErrorCode);
            }
            logs.Add(result);
        }
    }
}
